# -*- coding: utf-8 -*-

import os,logging,re
from .. import config as C
from .. import utils
from ..utils import fs
from ..utils import py
from ..build.caches.file_cache import FileCache

class ProtoPublisher:
	'''
		协议发布器
	'''
	def __init__(self):
		self._config = utils.getConfig()
		self._publishForce = py.getDictPath(self._config, 'publish.force', False)
		self._publishTarget = py.getDictPath(self._config, 'publish.target', [])
				
	def collectFiles(self,buildPackPath):
		'''
			收集协议文件
		'''
		files = fs.globFiles([ r'**/*' ], os.path.join(buildPackPath, 'compile', 'protos'))
		files = [ os.path.normpath(f) for f in files if os.path.isfile(f)]
		return files

	def checkUpdate(self):
		'''
			检测更新
		'''
		updates = set()
		for pack in os.listdir(C.BUILD_CACHES_PATH):
			fileCache = FileCache(os.path.join(C.BUILD_CACHES_PATH, pack, 'publish-protos-cache.json'))
			fileCache.load()
			files = self.collectFiles(os.path.join(C.BUILD_CACHES_PATH, pack))
			if fileCache.checkFileChange(files):
				updates.add(pack)
		return updates
	
	def publish(self):
		'''
			发布语言文件
		'''
		updates = self.checkUpdate()
		if self._publishForce or any(updates):
			decContent = []
			jsContent = []
			for pack in os.listdir(C.BUILD_CACHES_PATH):
				packPath = os.path.join(C.BUILD_CACHES_PATH, pack)
				jsPackContent = []
				inPath = os.path.join(packPath, 'compile', 'protos')
				if os.path.exists(inPath):
					for f in os.listdir(inPath):
						if f.endswith('.d.ts'):
							with open(os.path.join(inPath,f), 'r') as f:
								decContent.append(f.read())
						elif f.endswith('.js'):
							with open(os.path.join(inPath,f), 'r') as f:
								content = f.read()
								jsContent.append(content)
								jsPackContent.append(content)
				if len(jsPackContent) > 0:
					clientPath = utils.fullConfigPath(self._config['path']['client'])
					if os.path.exists(clientPath):
						clientPackPath = utils.getClientPackPath(os.path.join(clientPath,'assets'), pack)
						if clientPackPath != None:
							if not os.path.exists(clientPackPath):
								os.makedirs(clientPackPath)
							with open(os.path.join(clientPackPath, 'lcc-assets', 'lcc-protocols-%s.ts' % pack), 'w') as f:
								f.write('\n'.join(jsPackContent))

				fileCache = FileCache(os.path.join(packPath, 'publish-protos-cache.json'))
				fileCache.load()
				fileCache.updateFiles(self.collectFiles(packPath))
				fileCache.save()
			for target in self._publishTarget:
				decFile = None
				jsFile = None
				isServer = False
				if target == 'client':
					cpath = utils.fullConfigPath(self._config['path']['client'])
					if os.path.exists(cpath):
						decFile = os.path.join(cpath, '@types', 'lcc-protocols.d.ts')
				elif target == 'server':
					spath = utils.fullConfigPath(self._config['path']['server'])
					if os.path.exists(spath):
						decFile = os.path.join(spath, 'assets', 'lcc-assets', '@types', 'lcc-protocols.d.ts')
						jsFile = os.path.join(spath, 'assets', 'lcc-assets', 'lcc-protocols.js')
						isServer = True
				if decFile and len(decContent) > 0:
					fileDir = os.path.dirname(decFile)
					if not os.path.exists(fileDir):
						os.makedirs(fileDir)
					with open(decFile, 'w') as f:
						if isServer:
							f.write('\n'.join(decContent).replace('declare module "lcc"','declare namespace lcc'))
						else:
							f.write('\n'.join(decContent))
				if jsFile and len(jsContent) > 0:
					fileDir = os.path.dirname(jsFile)
					if not os.path.exists(fileDir):
						os.makedirs(fileDir)
					with open(jsFile, 'w') as f:
						f.write('\n'.join(jsContent))
			
		return True

def publish():
	return ProtoPublisher().publish()
